strcoll関数は、ロケール(地域情報)に基づき文字列を比較します。比較は、現在のロケールのLC_COLLATEカテゴリに応じて解釈された文字列に基づいて行われます。ロケールの設定・参照はsetlocale関数で行うことができます。

ロケールがデフォルトの’C’の場合は、strcoll関数とstrcmp関数の結果は同じです。

#include <string.h>
int strcoll(const char *s1, const char *s2);

*s1および、*s2は比較対象文字列を指定します。

戻り値として、次の値を返します。

  1. s1がs2より小さい場合は負の値を返します。
  2. s1とs2が等しい場合は0を返します。
  3. s1がs2より大きい場合は正の値を返します。

次の例題プログラムは、環境変数からロケールを取得して設定しています。

プログラム 例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>

/* メンバーの個人情報 */
struct member {
  int      number;         /* 番号 */
  char     name[20];       /* 名前(日本語) */
  double   height;         /* 身長 */
  double   weight;         /* 体重 */
  double   jump;           /* 最高到達点 */
};
/* qsort関数のソートキー比較関数 */
int SortComp(const void *, const void *);

int main()
{
  FILE             *fp;
  struct member    member_list[20];
  struct member    *list_ptr;
  int              list_max;
  int              list_cnt;

  /* ロケールを環境変数から取得して設定 */
  if (setlocale(LC_COLLATE, '') == NULL) {
    fprintf(stderr, 'ロケールが設定できませんでした\n');
    exit(EXIT_FAILURE);
  }

  if ((fp = fopen('beijing_2008_jp.csv', 'r')) == NULL) {
    fprintf(stderr, 'ファイルのオープンに失敗しました\n');
    exit(EXIT_FAILURE);
  }

  list_ptr = member_list;
  list_max = 0;
  /* メンバー情報入力 */
  while(fscanf(fp, '%d,%[^,],%lf,%lf,%lf',
      &list_ptr->number, list_ptr->name, &list_ptr->height,
      &list_ptr->weight, &list_ptr->jump) != EOF) {
    ++list_ptr;
    ++list_max;
  }
  fclose(fp);

  /* member_listを名前をキーにしてソート */
  qsort(member_list, list_max, sizeof(struct member), SortComp);

  list_ptr = member_list;
  printf('%-4s %-20s %-8s %-8s %s\n',
         '番号', '名前', '身長', '体重', '最高到達点');
  /* ソート後のメンバー情報出力 */
  for (list_cnt = 0; list_cnt < list_max; ++list_cnt, ++list_ptr) {
      printf('%3d  %-20s %6.1f %6.1f %6.1f\n',
        list_ptr->number, list_ptr->name, list_ptr->height,
        list_ptr->weight, list_ptr->jump);
  }

  return EXIT_SUCCESS;
}

/* qsort関数のソートキー比較関数 */
int SortComp(const void *p1, const void *p2)
{
  struct member *cmp1 = (struct member *)p1;
  struct member *cmp2 = (struct member *)p2;

  return strcoll(cmp1->name, cmp2->name);
}

例の実行結果

$ cat beijing_2008_jp.csv
1,栗原 ,186,69,305
2,多治見,180,70,309
3,竹下 ,159,52,280
4,大村 ,184,70,319
5,高橋 ,170,65,290
6,佐野 ,159,54,260
7,杉山 ,184,66,310
8,櫻井 ,167,63,290
9,狩野 ,174,65,298
11,荒木 ,186,79,307
12,木村 ,184,66,298
14,河合 ,168,63,280
$
$ ./strcoll.exe
番号 名前               身長   体重   最高到達点
 14  河合              168.0   63.0  280.0
  1  栗原              186.0   69.0  305.0
 11  荒木              186.0   79.0  307.0
  5  高橋              170.0   65.0  290.0
  6  佐野              159.0   54.0  260.0
  9  狩野              174.0   65.0  298.0
  7  杉山              184.0   66.0  310.0
  2  多治見             180.0   70.0  309.0
  4  大村              184.0   70.0  319.0
  3  竹下              159.0   52.0  280.0
 12  木村              184.0   66.0  298.0
  8  櫻井              167.0   63.0  290.0
$